{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Seaborn 数据准备和基本概念\n",
        "\n",
        "本部分将详细讲解 Seaborn 的数据准备和基本概念，包括数据格式要求、基本绘图流程和核心参数模式。\n",
        "\n",
        "## 学习内容\n",
        "1. 数据格式要求：DataFrame、长格式 vs 宽格式\n",
        "2. 基本绘图流程：从数据到图表的完整流程\n",
        "3. 核心参数模式：data、x、y、hue、size、style、col、row 等参数的使用\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "✓ 已设置中文字体: STHeiti\n"
          ]
        }
      ],
      "source": [
        "# 导入必要的库\n",
        "import seaborn as sns\n",
        "import matplotlib.pyplot as plt\n",
        "import pandas as pd\n",
        "import numpy as np\n",
        "import matplotlib.font_manager as fm\n",
        "import warnings\n",
        "warnings.filterwarnings('ignore')  # 忽略字体警告\n",
        "\n",
        "# 设置 Seaborn 样式\n",
        "sns.set_theme(style='whitegrid', font_scale=1.1)\n",
        "\n",
        "# 动态设置中文字体\n",
        "def setup_chinese_font():\n",
        "    \"\"\"自动检测并设置中文字体\"\"\"\n",
        "    import platform\n",
        "    system = platform.system()\n",
        "    \n",
        "    # 根据操作系统选择字体\n",
        "    if system == 'Darwin':  # macOS\n",
        "        chinese_fonts = ['PingFang SC', 'STHeiti', 'Arial Unicode MS', 'Hiragino Sans GB']\n",
        "    elif system == 'Windows':\n",
        "        chinese_fonts = ['Microsoft YaHei', 'SimHei', 'SimSun']\n",
        "    else:  # Linux\n",
        "        chinese_fonts = ['WenQuanYi Micro Hei', 'Noto Sans CJK SC', 'Droid Sans Fallback']\n",
        "    \n",
        "    # 获取系统所有可用字体\n",
        "    available_fonts = [f.name for f in fm.fontManager.ttflist]\n",
        "    \n",
        "    # 找到第一个可用的中文字体\n",
        "    selected_font = None\n",
        "    for font in chinese_fonts:\n",
        "        if font in available_fonts:\n",
        "            selected_font = font\n",
        "            break\n",
        "    \n",
        "    if selected_font:\n",
        "        plt.rcParams['font.sans-serif'] = [selected_font] + plt.rcParams['font.sans-serif']\n",
        "        print(f\"✓ 已设置中文字体: {selected_font}\")\n",
        "    else:\n",
        "        plt.rcParams['font.sans-serif'] = ['PingFang SC', 'Arial Unicode MS', 'SimHei'] + plt.rcParams['font.sans-serif']\n",
        "        print(\"⚠ 未找到推荐的中文字体，使用默认字体列表\")\n",
        "    \n",
        "    # 解决负号显示问题\n",
        "    plt.rcParams['axes.unicode_minus'] = False\n",
        "\n",
        "# 设置中文字体\n",
        "setup_chinese_font()\n",
        "\n",
        "# 在 Jupyter Notebook 中内联显示图形\n",
        "%matplotlib inline\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 1. 数据格式要求\n",
        "\n",
        "Seaborn 主要使用 Pandas DataFrame 作为数据源，理解数据格式对于正确使用 Seaborn 非常重要。\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 1.1 使用 Pandas DataFrame\n",
        "\n",
        "Seaborn 的核心设计理念是使用 **Pandas DataFrame** 作为数据源。DataFrame 的列名可以直接作为变量名传入绘图函数。\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "数据形状: (244, 7)\n",
            "\n",
            "列名: ['total_bill', 'tip', 'sex', 'smoker', 'day', 'time', 'size']\n",
            "\n",
            "前5行数据:\n",
            "   total_bill   tip     sex smoker  day    time  size\n",
            "0       16.99  1.01  Female     No  Sun  Dinner     2\n",
            "1       10.34  1.66    Male     No  Sun  Dinner     3\n",
            "2       21.01  3.50    Male     No  Sun  Dinner     3\n",
            "3       23.68  3.31    Male     No  Sun  Dinner     2\n",
            "4       24.59  3.61  Female     No  Sun  Dinner     4\n"
          ]
        },
        {
          "data": {
            "image/png": "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UVGRnnvuOf3000867LDDdOutt+q4445rEt/evXs1d+5cvfPOOyouLlZWVpYGDRqkcePGqX///gFd4759+zR58mRZrVY9+OCD+s1vfqNLL71Ut9xyiy699FKNHz9el1xyiSQpLy/P77GOPvpo1dfXa+rUqTr++OPVsWNHr4K+29NPP62nn37a8/Onn36qJUuW6KqrrtJNN90kSbrvvvtksVh01113yWq16q9//aueeOIJrVy5Uk899ZRqamokSR9++KEk6aqrrmpynmeffVbHHHNMQPehceLsdDpVW1ur8vJyZWZmNvv+n3/+WfPnz1dtba2mTZumadOmebZNmTJFEydODCgOANGJhAFAVHn11Vflcrk8P9vtdq1atUrZ2dlKS0uTxWJRTU2NbDabvvvuOzkcDtlsNpWXl6tHjx6G4w727t2r1157zfOzu+D8n//8x6u70ObNm0N6Pfn5+RozZowWLVqkiRMnemp0S0tLdeWVV+qnn37SBRdcoCOOOEJVVVV65513NGLECN14441exxk2bJj69u2rxx57TBkZGbrssss8XUgkafv27briiivkcDh0wQUXqGfPniorK9Nrr72mESNGeGqyW+LBBx+U1WrVHXfcodNPP93z+sMPP6y5c+fqlFNO0a233iqr1aqvv/5af/nLX/TVV18ZHu/mm2/Whg0bdPnll8tqtepf//qXxo0bp8WLF+v555/XRx99pDFjxigzM1Mvv/yyrrrqKi1ZssSrC9rWrVt1xRVXKDc3V5deeqk6d+6skpISvfXWW7rgggt055136oILLvB7XaWlpbrqqqv0888/64knntBvfvMbSdKAAQO0ZMkSTZw4Ub169Qoqefzvf/+rH3/8UbfccosSExP1zDPPKCsrS6mpqUpKStKf/vQnnXDCCZ7xDzfeeKMOOeQQXXfddZ4WqN27d6u+vt7TkuEePOz+vUhISJDT6dSWLVv01VdfaerUqbr66qu1c+dOnXrqqZo+fbouvvjiJi0h9fX12rVrlzIzMz3jgRqrq6tTbW2tqqurVV1d7TVewkhNTY1uuOEGOZ1OPfHEE57E6pZbbtHevXs1duzYgO8fgOhEwgAgarhcLhUVFXm9VldXZziY88wzz/T6+ZFHHjFMGLZu3dqkEC5J99xzT8uCDcLZZ5+tp556Sps2bfIMJL7ppptUUVGhV155xatmd/To0XrxxRd11113eR2jZ8+e6tmzp55//nnl5uZ6dSNyOp265pprlJ2draefftorkbjkkkv0yCOP6NFHH/UZm3vcRWMN+5kXFxfrjTfekNVq9bz26quvat68ebr//vt13nnneV4/88wzdfHFF+uyyy5TcXFxk+Nu27ZN6enpWrJkied4w4YN01lnnaWbbrpJCQkJWrp0qdLT0yVJZ511ls477zw9//zzuvvuuyUdGFx87bXXasiQIbrzzju9jn/55Zdr0aJFuvvuu9W/f3/99re/9XndW7du1dixY7Vr1y5df/316tatm3bv3q2EhATPoGV3i0NpaanPY/iycOFC5eXl6dRTT5XJZGrSMpKYmKj09HTPZ56cnKy0tDSvLj8ffvihpk+fLovFIovFosTERI0ePVoul0u1tbU677zz5HQ6dcEFF8hqtXoSI/eMYrm5uT4HFdfW1urUU0/1GfeQIUOavHbEEUd4jbXwxWazadKkSfr555910UUX6W9/+5vmz5+vxYsX69tvv9XTTz/NAGegHSBhABA1lixZoh9//NHTj1v6teB63XXXeRIHd0Hv9ddflyR99NFHuuKKK/wOpiwsLNScOXM8Py9cuFBz5szRyy+/7KlZlqRnnnlG8+bNC+l1uft5//zzz+rbt68+/fRTffjhhyoqKvI5uHjUqFH64osvmi2sua1YsULbt2/XG2+84ZUsuE2ZMkWff/65zxmRGg/AdVu2bJkyMjIkSSNGjPBKFqQDydnIkSO9kgW3Qw89VA888IDPVg2Xy6U///nPXsdLSUnR4MGDVVRUpPnz53uSBUlKSkrS4MGD9fHHH3tee+2111ReXq5rr73WZ7IzfPhwLV++XEVFRU0GEzeMMTExUdddd51mzpypmTNnNtnn1ltv9ep+1ZzXX39dH330kSZMmKCNGzeqqqpKRx11lM444wylpqbKYrFo9+7deu211/Tll19KOtCideihh3od58wzz9RZZ53luf6Gg5nds3l98cUXuvLKK3XmmWfq+++/V2Fhofbv3y9Jhq0CFotFycnJ+u1vf6vRo0f7vZYHHnggoMHJycnJOuWUUzRx4kQVFhaqpKREZ599tlwulx599FENGjSo2WMAiH4kDACiwu7du/XAAw/oyCOPVEpKimprayXJMzNMY4G+5mY2m726Hrm7f2RmZnq93jBZCZXExEQl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W7Zs0Z133ql3331Xf/jDH2S1WrV+/XotXrxYV155ZbPdXlrKYrF4rnf48OG68MILdfDBB2vnzp1atmyZfv75Z82ZM0e5ublBHTc5OVmfffaZp2vU22+/rUGDBsnhcOi4445rdtagrKws/eEPf9ATTzzhOfcLL7zgWT8kISFB559/vk488URNmTJF9fX1cjqdstlshl27Zs+e7bVgn9S05aNbt26qr69XdnZ2k+SzoUcffVRDhw71DIouLS1VSkqKkpOT9fPPP+v555/XqaeeqsLCQlVXV+vaa69Vbm5uQM9NcXGx5s2bp927dys3N1dnn312s+tgAIgdJAwAoo57lhW39PR0LVq0SFdddZUeeughWa3WgAuDL730kpKSkpp0/bHZbJIC63bRXKwNV3BOSkpSenq6DjvsMI0bN04XX3xxkxp/6cC4g+eff17PPPOMVqxYoaKiImVmZur3v/+9li9f7nMNA+nAlKu33HKLpk2bpvnz53sSkby8PC1dulTz58/XihUrtGvXLnXq1Emnn366rr32Ws+KwKF0ww03aODAgXrmmWf0wAMPqK6uTv369dPDDz+sk08+uc0SBknq3bu3li1bpnnz5qmoqEjFxcXq1KmTjj32WM2aNSvgVcAbcycLdXV1mjt3rkpLS/XOO+/omWeeafa9X3/9tZ555hmdeOKJWrFihX755RfdeOONXitEH3nkkerRo0eTqU/d3YUajuOor6/3Oej51Vdf9fy8atUqTZ48WQcffLD27NmjkSNH6o477tDJJ5/sdfyPPvpIc+fOVadOndS/f3+9/fbbmjRpkh599FGddtppSkhI0BNPPKE9e/aosLBQKSkpOuigg/TSSy/ptNNOa9L60bi1pXPnznrvvfe0bt06vfzyyyoqKtLChQv173//2ysZqqurk9PpDGgGJgDRw+QKZsoEAAiDYcOGKSsrS88//7ykA7X4L7zwgv7+978rNTVVDodD5eXlOuSQQzRo0CB16tRJnTp1UnJysgoKCjytCe+8846uueYa/fGPf9SsWbO8znH33XfrueeeU1FRkQYNGqSNGzdqy5Ytevrpp/Xtt9/qP//5jw455JCwXzvCy+FwqLCwUPn5+TrhhBNkNptlt9u1Zs0affXVV5o8ebKuvfZauVwu2e122e123XDDDdqxY4feffddz3G2bNmiyy67TKmpqXr11Ve1Z88eTZ8+XV988YXy8vLUt29fZWdny2q1qq6uTpWVldq3b59KSkq0e/duFRcXa/ny5erVq5fnmIWFhbryyis1adIkOZ1OLVmyREuWLNHevXv1/PPP6x//+IdeffVV9erVS08//bS2b9+ua6+9Vvv27VPPnj117733qrCwUDU1Nbrwwgu1a9cu/ec//1Fqaqp27NihIUOGaMKECbrhhhskSeedd55+/PFHffTRR7JYLNq7d69+//vfKzs7W6+99prXGKMBAwbo6KOP1i233OLzvu7Zs0fr1q3zmlTgH//4h1auXKlPP/2UaVaBGEMLA4CoU15erqysLJWWlmrJkiVatmyZtm7dqqOPPloPP/ywUlNTtWLFCr399tt66623PLWdCQkJnrnw6+vrPasbX3bZZU3OMWHCBF100UWe8Qvr16/XbbfdJulA7X/jLkRonywWi26++WY999xzWrhwoaqrq5WUlKTc3FxNmDBB48eP9+w7fvx4z1oW/fr18zpOcnKy8vLydNdddyktLU1paWl67rnn9M0332jFihX6+uuv9dVXX6m0tNRnq9ZBBx3klSy4B/K7mc1mffXVV9q8ebMmTJighIQE/fjjjzrzzDN19913Kz09Xbm5uVqxYoUef/xxffTRR54Y7733Xn377beaNGmSZ7yHe6D/559/7jnH7373O+3du1fffvutBgwYoI4dO+r000/XunXrtGHDBk8rXX19vex2u9577z299957fu/vQw895Pl3dna2unTpourqahIGIMbQwgAg6vTv31/9+vXTU089pUmTJumnn37ShAkTNGLECCUmJnrt63Q6tWHDBm3evFkVFRVei5DZ7XYtW7ZMF110UbPn3Ldvn/71r38pPz9fRx11lNdqw4Ak/fvf/9azzz6rPn366MILL/Ss4O3mcrkCmunJ3S2nvr5eiYmJMpvNAQ0OttlsSkpK8symZDSzUuNtpaWlWr58uYYPH+7pHudyufTFF1/oN7/5jc8F9twqKyuVlpYW8AxWANonEgYAUc1ut8tisTRJFAAAQHiQMAAAAAAwxATJAAAAAAyRMAAAAAAwRMIAAAAAwFDcT6u6du1auVwuFpEBAABA3HAvklpYWNjsvnHfwuByucS47/jicrnkcDj43OGF5wJGeDbgC88FfIml5yKYMnDctzC4WxbcK8Oi/bPZbNqwYYMO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OOEE3XXXXbJarU323bdvnx566CENGzZMDzzwQOujbaC4uFh33nmnrr32WlkslpAeGwAAAMABQScMkvTss8/q+++/V1lZmVJTUzV//nw999xzSk1NVUZGhrKysnTQQQcpPz9ft912m0aMGBHquDV9+nT17t1bl156aciPDQBANKiwObS/skZVdqfSUs3KSk9WhpVKMgDh1aKEoXPnzvr555+1YcMGnXDCCTrqqKOUnp6upKQk1dfXy2azqbi4WM8//7x2796tjz/+WH/96199tkK0xKJFi/TFF19o+fLlTcZPAADQHpTss2vW4rVau6nE81phfq4mjS5UbnZqBCMDEG+CThicTqeGDh2qcePGacGCBfrggw9ksVhUUFDQZN9rr71Wixcv1mOPPaZffvlFTzzxhFJTW/clt3XrVs2YMUM333yzDj300FYdCwCAaFRhczRJFiRp7aYSzVq8VtPGDKKlAUDYBJ0wVFVVqaqqSpJUXV2tDz/8UB9++GGT/Uwmk+6//35NmjRJJpNJs2fP1t///nfdeeedLQ62vr5ef/nLX1RTU6PnnntOjz32mI4//nhNnz5dHTt2bPFxXS6XbDZbi9+P2GK3273+BiSeCxiLxLNRVl7bJFlwW7upRGXl1UpUbdjiQVN8Z8CXWHouXC5XwD11TC6XyxXMwTdu3KjvvvtOBx10kLp3767ExESvk23cuFF5eXkym81KS0vzdEM677zztH//fr3xxhstHqT8yiuv6JZbbtGVV16pM844Q+Xl5Zo9e7Zqamq0ePFiz2DsYKxfv55ZlgCgnUtISFBmdicpMVU2R52syYlSrV3l+/aovr4+0uE1Ycnqqj8//onh9vsmHivH/h1hjAhAe2SxWNS/f/9m9wu6hH3ooYfqnHPOkclkUlFRkV5//XVNmTJF6enpcjqduvPOO1VQUKDbb79d9fX1qqysVFVVlS666CINGTKkVTMaLV26VBdddJFuvvlmz2uFhYU644wztHLlSp1++uktOq7ZbNbhhx/e4rgQW+x2u7Zt26bu3bu3uosc2g+ei/atstql2UvWNRkPcN35BUpP8V/DFolnY0+5/9aDrPRUdTqkb1higW98Z8CXWHouvvvuu4D3DTphSElJkSS9+OKL6tu3ry6++GK9+eabmjFjhr7//nvt3btXI0aM0NFHH92kmWPUqFHBns7LL7/8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ysrKCESKcFu5cqVGjhyp/v3767jjjtPtt9+u/fv3e7bzbMSnt99+W+eee64GDBigM888Uy+++KLXdp4LSNL69ev10ksveX7muYhfNTU1+u1vf6v8/HyvP6tXr5bUvp4NEga0W/369dOqVatUWFjYZNumTZt0xRVXaNCgQVq+fLkef/xxfffddxo/frzq6+sjEC3CZenSpbr55pt13nnn6dVXX9XMmTP13Xff6fLLL5fD4eDZiFMrV67U1KlTddFFF+nVV1/V9ddfr4cfflhz586VxHcGDqisrNSNN94oh8Mhieci3m3cuFGZmZn64IMPvP4UFha2v2fDBbRzY8aMcT333HNer11zzTWuW2+91eu1yspK18knn+xatmxZOMNDGNXW1rqOPfZY1wsvvOD1emVlpWvw4MGuV155hWcjTo0YMcL12GOPeb22ePFi17HHHutyufjOwAE33nijq3fv3p7/U3gu4ltRUZHriiuu8LmtvT0btDAg7jidTr3//vu66KKLvF5PS0vTqFGj9Prrr0coMrS1HTt2yG63a9iwYV6vp6WlqaCgQFu3buXZiFMvvfSSrrnmGq/XzGaz6urq+M6AJOnFF1/UqlWr1L17d0n8XwLp22+/Vd++fZu83h6fDRIGxJ0ff/xRdXV16tOnT5NtAwYM0IYNGyIQFcIhLy9PX375pdLT071ed7lc+u6772SxWHg24lRiYqLn3w6HQ//97381Y8YMXXTRRXxnQFu3btV9992n++67T507d5bE/yU4kDC8+eabGjx4sE455RTdd999stls7fLZIGFA3Nm/f78yMjJksViabOvYsaNKS0sjEBUiqaioSBUVFTruuON4NuJcRUWFjjzySI0fP14dOnTQVVddxXdGnKupqdGUKVM0cuRIDR061PM6z0V8c7lcGjRokG6//XY98cQTuu222/TJJ59o/Pjx2rdvX7t7NpIiHQAQbi6Xy+92k8kUpkgQDd577z09+OCDmj9/Ps8GlJaWpiVLluiHH37QokWLdNFFF+n222/3+x6ei/bt3nvvVVJSkm6++Wav1/m+iG8mk0l//vOfPT/n5+ersLBQZ5xxhj799NNm3xtraGFA3MnOzlZlZaXq6uqabNu7d69ycnIiEBUi4bPPPtOUKVP0t7/9TUcffTTPBpSQkKB+/frp7LPP1sKFC5WUlKRPP/2U5yJO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RkVFRaqqqlKHDh0kHZiGdfz48crLy9OiRYtkMpn06KOP6oMPPtD111+v2tpaSdKECRPkdDr12Wef6aqrrtLEiRN9JjIAABIGAIh7dXV1slgsnp//7//+Tx9//LEkadSoUT7f880333glGZJ0ySWXNNnvxhtvbPb8Xbp00XXXXaeDDz5Yxx13nDZu3Kj6+nolJycrISFBZ555pi6++GJddNFFqqmpkc1mU48ePdShQwedffbZqqys9Bzr3nvv1f79+zVq1ChdeeWVGjJkiKc7VWZmpqclQjowVqKoqEg33HBDszECQDwjYQCAOFdbW+uZNUmSZs6cqS+//FJXX321PvvsM02dOlVHHnmkJk2apNraWlVWVjZJFqQDXZK6du0qSVqzZo0uueQSPfvss16zGp1wwgk+YzjvvPM8/+7Tp0+T7VlZWerZs6fP96anp3v+fe+996q8vFxWq1Vr167VggULZLVatX37dh199NFe7zObzUpNTfV5TADAr0gYACAONVxcraKiQt26dZMkOZ1OZWVleU0v2q9fP3388ceaNGmSkpKSlJ2d7fNYP/30k2cdhF27dnn+3rp1q2dff4uoFRcX68cff1RKSorMZrNXUlJWVqatW7fK5XKptrZWDodDJpNJ/fv39zpGQkKCsrOz9dJLL+m1117TrbfeKqfTqYceekgLFizQ3/72N69YMjIyArpfABDPSBgAIA7Z7XbPvzdt2qQhQ4Zoz549qqqqarLv0Ucfrblz5+qnn37SoYce2mS7zWaTyWTSuHHjPOMA3IOVp0+frsTERE9SUVtb6xlH0NgHH3zgteBbQ0VFRZ6B1G59+vTRK6+84vXa5s2b9dBDD+n999/XLbfcoqFDh8rlcqlv375atmyZJzFy34OsrCzPz41XqAYAHEDCAABxasiQIbLb7SouLtaAAQPkdDrVuXPnJvsde+yx6tatm2bOnOk1XWpNTY1qa2s1ZswYr8XRpF+7JD3zzDNNFlpzOp2y2WxKSEjwask4/fTT9fvf/17r16/X7373O1mtVplMJh1xxBGaOHGirrvuOtXX1+utt95Sv379lJmZ2STWt956Szt27FB9fb2efPJJPf3006qvr1dJSYk++eQTOZ1Oz767d+/2WkjO4XAEfQ8BIB6QMABAHOrdu7fmzJmjhx9+WL169VJlZaU+//xzTZgwocm+dXV1uvLKK3XHHXfokEMO8Qxkfu211zwtAklJSUpKSlJiYqISEhI8XY/cC6zV19errq5OdXV1nkL79ddfr2uuucZzHqvVqs8++0xXX321xo8f32TAtMlkUm1trW699VYdddRReuqpp5rEOmnSJJ177rkaMmSIXn75ZeXm5mrHjh0aMmSIEhMTZbFYdP/99ysvL0/vv/++LrzwQpWVlempp55iliQAMEDCAABxatOmTXr66af1wAMPaNu2bXr44YeVkpKiyy+/XPv27ZMkvfDCC/r3v/+tF154QStXrtS8efP08ccf6//+7/90xBFHaPr06bJarbJYLJ5xByaTSd9//70efvhhjRs3Tr169fKMPaitrVVNTY3sdnuT8QeSdPLJJ+vEE0/UBx98oOuuu85r9iZJevvtt5WWlqYZM2Y0e33V1dWqqqpSdXW157W0tDSdd955mjVrln755Rd16tRJp556qm688UZdeumlrbuhANBOkTAAQBzauXOnxo8fr+OOO07Dhg2TJG3fvl1FRUW68MILtWLFCknSQw89pPPOO09Op1MzZszQddddp8rKSnXp0kUpKSnKz8/3efxPP/1UklRYWKjjjz++2Xg+++wzvf7660pNTVWPHj2UnZ2tBQsWyGQyyeVy6YsvvtCTTz6p5cuXq0+fPnrhhRdkt9tlMpmaTIvqHoswdOhQr9erqqqUkZGhxx57TLNnz9aZZ56pESNG6KOPPtI999yj7du36y9/+QstDQDQCAkDAMSZ+vp63X333TKZTHrggQc8r19//fW65JJLlJKSIqfTqW7duun+++/XoEGDJEkWi0ULFizQL7/84jX2wBd3t6NAxwVs27ZNzz33nCwWi5KTkz1dnCQpNzdXW7Zs0ZYtW+R0OrVz50599tlncjqd6tKlS5OEoaKiQtKBQdQNuyStWrVK//rXv/TNN99o4MCB+utf/yqLxaJ//OMfMpvNWrhwoTp27KiJEycGdiMBIE6QMABAnElISNDcuXNVXFysnJwcz+tms1kHH3ywJOmee+5RcnJyk2lHzWazz5mSGnPPttRwUTV/zjnnHJ177rk+13cwUldX59XdyG3//v1eP3ft2lWbNm1SaWmp5s6dqwsuuEC33HKL0tLSJB0YG3H//fcrNzdXF198ccDnB4B4YXIxjxwAIE5UV1c32zoCAPBGwgAAAADAUEKkAwAAAAAQvUgYAAAAABgiYQAAAABgiIQBAAAAgCESBgAAAACGSBgAAAAAGCJhAAAAAGCIhAEAAACAof8Heu5w6LycQmkAAAAASUVORK5CYII=",
            "text/plain": [
              "<Figure size 800x600 with 1 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# 示例：使用 DataFrame 作为数据源\n",
        "# 加载 Seaborn 内置数据集\n",
        "tips = sns.load_dataset('tips')\n",
        "\n",
        "# 查看数据结构\n",
        "print(\"数据形状:\", tips.shape)\n",
        "print(\"\\n列名:\", tips.columns.tolist())\n",
        "print(\"\\n前5行数据:\")\n",
        "print(tips.head())\n",
        "\n",
        "# 使用 DataFrame 创建图表\n",
        "fig, ax = plt.subplots(figsize=(8, 6))\n",
        "sns.scatterplot(data=tips, x='total_bill', y='tip', ax=ax)\n",
        "ax.set_title('使用 DataFrame 创建散点图', fontsize=14, fontweight='bold')\n",
        "ax.set_xlabel('账单金额')\n",
        "ax.set_ylabel('小费金额')\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 1.2 长格式 vs 宽格式\n",
        "\n",
        "数据有两种主要格式：\n",
        "\n",
        "- **长格式（Long Format）**：每行代表一个观测值，每个变量占一列 （就和数据库表的格式一样，第一列可以重复）\n",
        "    A\n",
        "    A\n",
        "    B\n",
        "- **宽格式（Wide Format）**：每个变量在不同列中，时间序列或分组数据通常以这种方式存储(第一列不能重复)\n",
        "    A\n",
        "    B\n",
        "    C\n",
        "\n",
        "Seaborn 更适合使用**长格式**数据。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "宽格式数据：\n",
            "  产品  2020  2021  2022\n",
            "0  A   100   120   140\n",
            "1  B   150   180   200\n",
            "2  C   120   140   160\n",
            "\n",
            "==================================================\n",
            "\n",
            "长格式数据：\n",
            "  产品    年份  销售额\n",
            "0  A  2020  100\n",
            "1  B  2020  150\n",
            "2  C  2020  120\n",
            "3  A  2021  120\n",
            "4  B  2021  180\n",
            "5  C  2021  140\n",
            "6  A  2022  140\n",
            "7  B  2022  200\n",
            "8  C  2022  160\n"
          ]
        }
      ],
      "source": [
        "# 示例：长格式 vs 宽格式\n",
        "\n",
        "# 创建宽格式数据（示例：不同年份的销售额）\n",
        "wide_data = pd.DataFrame({\n",
        "    '产品': ['A', 'B', 'C'],\n",
        "    '2020': [100, 150, 120],\n",
        "    '2021': [120, 180, 140],\n",
        "    '2022': [140, 200, 160]\n",
        "})\n",
        "\n",
        "print(\"宽格式数据：\")\n",
        "print(wide_data)\n",
        "print(\"\\n\" + \"=\"*50 + \"\\n\")\n",
        "\n",
        "# 使用 pd.melt() 转换为长格式\n",
        "long_data = pd.melt(wide_data, \n",
        "                     id_vars=['产品'],  # 保留的标识列\n",
        "                     value_vars=['2020', '2021', '2022'],  # 要转换的列\n",
        "                     var_name='年份',  # 新变量列名\n",
        "                     value_name='销售额')  # 新值列名\n",
        "\n",
        "print(\"长格式数据：\")\n",
        "print(long_data)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 1.3 使用 pd.melt() 转换数据格式\n",
        "\n",
        "`pd.melt()` 是 Pandas 提供的函数，用于将宽格式数据转换为长格式，这是使用 Seaborn 绘图前的常见数据准备步骤。\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例：使用 pd.melt() 转换数据并绘图\n",
        "\n",
        "# 宽格式数据\n",
        "wide_data = pd.DataFrame({\n",
        "    '产品': ['A', 'B', 'C', 'D'],\n",
        "    'Q1': [100, 150, 120, 130],\n",
        "    'Q2': [120, 180, 140, 150],\n",
        "    'Q3': [140, 200, 160, 170],\n",
        "    'Q4': [160, 220, 180, 190]\n",
        "})\n",
        "\n",
        "print(\"原始宽格式数据：\")\n",
        "print(wide_data)\n",
        "\n",
        "# 转换为长格式\n",
        "long_data = pd.melt(wide_data, \n",
        "                     id_vars=['产品'],\n",
        "                     value_vars=['Q1', 'Q2', 'Q3', 'Q4'],\n",
        "                     var_name='季度',\n",
        "                     value_name='销售额')\n",
        "\n",
        "print(\"\\n转换后的长格式数据：\")\n",
        "print(long_data)\n",
        "\n",
        "# 使用长格式数据绘图\n",
        "fig, axes = plt.subplots(1, 2, figsize=(14, 5))\n",
        "\n",
        "# 使用长格式数据创建条形图\n",
        "sns.barplot(data=long_data, x='产品', y='销售额', hue='季度', ax=axes[0])\n",
        "axes[0].set_title('长格式数据：按产品和季度分组', fontsize=12, fontweight='bold')\n",
        "\n",
        "# 使用长格式数据创建线图\n",
        "sns.lineplot(data=long_data, x='季度', y='销售额', hue='产品', marker='o', ax=axes[1])\n",
        "axes[1].set_title('长格式数据：各产品季度趋势', fontsize=12, fontweight='bold')\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 1.4 数据列名作为变量名\n",
        "\n",
        "在 Seaborn 中，DataFrame 的列名直接作为变量名传入绘图函数。这是 Seaborn 的核心设计理念，使得代码更加简洁和直观。\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例：使用列名作为变量名\n",
        "tips = sns.load_dataset('tips')\n",
        "\n",
        "# 直接使用 DataFrame 的列名\n",
        "# 'total_bill' 和 'tip' 是 DataFrame 的列名\n",
        "sns.scatterplot(data=tips, x='total_bill', y='tip')\n",
        "\n",
        "plt.title('使用列名作为变量名', fontsize=14, fontweight='bold')\n",
        "plt.xlabel('账单金额（total_bill 列）')\n",
        "plt.ylabel('小费金额（tip 列）')\n",
        "plt.tight_layout()\n",
        "plt.show()\n",
        "\n",
        "# 注意：如果列名不存在，会报错\n",
        "# sns.scatterplot(data=tips, x='不存在的列', y='tip')  # 这会报错\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 2. 基本绘图流程\n",
        "\n",
        "Seaborn 的基本绘图流程包括：准备数据、选择图表类型、调用函数、定制图表、显示或保存。\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 2.1 完整绘图流程\n",
        "\n",
        "1. **准备数据**：确保数据是 DataFrame 格式，且为长格式\n",
        "2. **选择图表类型**：根据数据特点选择合适的图表类型\n",
        "3. **调用 Seaborn 函数**：使用相应的绘图函数\n",
        "4. **使用 Matplotlib 进行额外定制**：添加标题、标签、调整布局等\n",
        "5. **显示或保存图表**：使用 `plt.show()` 显示或 `plt.savefig()` 保存\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例：完整的绘图流程\n",
        "\n",
        "# 步骤1：准备数据（DataFrame 格式）\n",
        "tips = sns.load_dataset('tips')\n",
        "print(\"步骤1：数据已准备\")\n",
        "print(f\"数据形状: {tips.shape}\")\n",
        "print(f\"列名: {tips.columns.tolist()}\\n\")\n",
        "\n",
        "# 步骤2：选择图表类型（散点图）\n",
        "print(\"步骤2：选择散点图来展示两个连续变量的关系\\n\")\n",
        "\n",
        "# 步骤3：调用 Seaborn 函数\n",
        "fig, ax = plt.subplots(figsize=(10, 6))\n",
        "sns.scatterplot(data=tips, x='total_bill', y='tip', hue='time', ax=ax)\n",
        "print(\"步骤3：已调用 sns.scatterplot()\\n\")\n",
        "\n",
        "# 步骤4：使用 Matplotlib 进行额外定制\n",
        "ax.set_title('账单金额与小费关系分析', fontsize=16, fontweight='bold')\n",
        "ax.set_xlabel('账单金额（美元）', fontsize=12)\n",
        "ax.set_ylabel('小费金额（美元）', fontsize=12)\n",
        "ax.legend(title='用餐时间', loc='upper left')\n",
        "ax.grid(True, alpha=0.3)\n",
        "print(\"步骤4：已添加标题、标签和图例\\n\")\n",
        "\n",
        "# 步骤5：显示图表\n",
        "plt.tight_layout()\n",
        "plt.show()\n",
        "print(\"步骤5：图表已显示\")\n",
        "\n",
        "# 如果需要保存图表，可以使用：\n",
        "# plt.savefig('scatterplot.png', dpi=300, bbox_inches='tight')\n",
        "# print(\"图表已保存为 scatterplot.png\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 2.2 数据准备示例\n",
        "\n",
        "在实际应用中，数据通常需要清洗和转换才能用于可视化。\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例：数据准备和清洗\n",
        "\n",
        "# 创建示例数据（模拟真实场景）\n",
        "np.random.seed(42)\n",
        "raw_data = pd.DataFrame({\n",
        "    '日期': pd.date_range('2023-01-01', periods=100, freq='D'),\n",
        "    '销售额': np.random.normal(1000, 200, 100),\n",
        "    '产品类别': np.random.choice(['A', 'B', 'C'], 100),\n",
        "    '地区': np.random.choice(['北京', '上海', '广州'], 100)\n",
        "})\n",
        "\n",
        "# 添加一些缺失值（模拟真实数据）\n",
        "raw_data.loc[10:15, '销售额'] = np.nan\n",
        "raw_data.loc[50:52, '销售额'] = np.nan\n",
        "\n",
        "print(\"原始数据：\")\n",
        "print(f\"形状: {raw_data.shape}\")\n",
        "print(f\"缺失值数量: {raw_data['销售额'].isna().sum()}\")\n",
        "print(f\"\\n前5行:\")\n",
        "print(raw_data.head())\n",
        "\n",
        "# 数据清洗：处理缺失值\n",
        "cleaned_data = raw_data.dropna()  # 删除缺失值\n",
        "# 或者使用填充：cleaned_data = raw_data.fillna(raw_data['销售额'].mean())\n",
        "\n",
        "print(f\"\\n清洗后数据形状: {cleaned_data.shape}\")\n",
        "print(f\"缺失值数量: {cleaned_data['销售额'].isna().sum()}\")\n",
        "\n",
        "# 使用清洗后的数据绘图\n",
        "fig, axes = plt.subplots(1, 2, figsize=(14, 5))\n",
        "\n",
        "# 按产品类别分组\n",
        "sns.boxplot(data=cleaned_data, x='产品类别', y='销售额', ax=axes[0])\n",
        "axes[0].set_title('按产品类别分组的销售额分布', fontsize=12, fontweight='bold')\n",
        "\n",
        "# 按地区分组\n",
        "sns.barplot(data=cleaned_data, x='地区', y='销售额', ax=axes[1])\n",
        "axes[1].set_title('不同地区的平均销售额', fontsize=12, fontweight='bold')\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 3. 核心参数模式\n",
        "\n",
        "Seaborn 的绘图函数遵循统一的参数模式，理解这些核心参数对于掌握 Seaborn 非常重要。\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 3.1 data 参数 - 数据源\n",
        "\n",
        "`data` 参数指定数据源，通常是 Pandas DataFrame。当指定 `data` 参数后，`x`、`y` 等参数可以直接使用列名（字符串）。\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例：data 参数的使用\n",
        "tips = sns.load_dataset('tips')\n",
        "\n",
        "# 方法1：使用 data 参数（推荐）\n",
        "fig, ax = plt.subplots(figsize=(8, 6))\n",
        "sns.scatterplot(data=tips, x='total_bill', y='tip', ax=ax)\n",
        "ax.set_title('方法1：使用 data 参数（推荐）', fontsize=14, fontweight='bold')\n",
        "plt.tight_layout()\n",
        "plt.show()\n",
        "\n",
        "# 方法2：不使用 data 参数（需要直接传入数组）\n",
        "fig, ax = plt.subplots(figsize=(8, 6))\n",
        "sns.scatterplot(x=tips['total_bill'], y=tips['tip'], ax=ax)\n",
        "ax.set_title('方法2：不使用 data 参数', fontsize=14, fontweight='bold')\n",
        "plt.tight_layout()\n",
        "plt.show()\n",
        "\n",
        "# 推荐使用方法1，因为：\n",
        "# 1. 代码更简洁\n",
        "# 2. 可以方便地使用其他参数（如 hue、style 等）\n",
        "# 3. 更符合 Seaborn 的设计理念\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 3.2 x 和 y 参数 - 坐标轴变量\n",
        "\n",
        "`x` 和 `y` 参数指定 x 轴和 y 轴的变量名（列名）。当使用 `data` 参数时，这些参数应该是 DataFrame 的列名（字符串）。\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例：x 和 y 参数的使用\n",
        "tips = sns.load_dataset('tips')\n",
        "\n",
        "fig, axes = plt.subplots(1, 2, figsize=(14, 5))\n",
        "\n",
        "# 散点图：x='total_bill', y='tip'\n",
        "sns.scatterplot(data=tips, x='total_bill', y='tip', ax=axes[0])\n",
        "axes[0].set_title('散点图：x=账单金额, y=小费金额', fontsize=12, fontweight='bold')\n",
        "axes[0].set_xlabel('账单金额（total_bill）')\n",
        "axes[0].set_ylabel('小费金额（tip）')\n",
        "\n",
        "# 箱线图：x='day', y='tip'\n",
        "sns.boxplot(data=tips, x='day', y='tip', ax=axes[1])\n",
        "axes[1].set_title('箱线图：x=日期, y=小费金额', fontsize=12, fontweight='bold')\n",
        "axes[1].set_xlabel('日期（day）')\n",
        "axes[1].set_ylabel('小费金额（tip）')\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 3.3 hue 参数 - 用颜色区分类别\n",
        "\n",
        "`hue` 参数用于根据分类变量用不同颜色区分数据点或分组。这是 Seaborn 最常用的参数之一。\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例：hue 参数的使用\n",
        "tips = sns.load_dataset('tips')\n",
        "\n",
        "fig, axes = plt.subplots(2, 2, figsize=(14, 10))\n",
        "\n",
        "# 1. 散点图：按用餐时间（time）用颜色区分\n",
        "sns.scatterplot(data=tips, x='total_bill', y='tip', hue='time', ax=axes[0, 0])\n",
        "axes[0, 0].set_title('散点图：hue=用餐时间', fontsize=12, fontweight='bold')\n",
        "\n",
        "# 2. 箱线图：按吸烟与否（smoker）用颜色区分\n",
        "sns.boxplot(data=tips, x='day', y='tip', hue='smoker', ax=axes[0, 1])\n",
        "axes[0, 1].set_title('箱线图：hue=是否吸烟', fontsize=12, fontweight='bold')\n",
        "\n",
        "# 3. 条形图：按用餐时间用颜色区分\n",
        "sns.barplot(data=tips, x='day', y='tip', hue='time', ax=axes[1, 0])\n",
        "axes[1, 0].set_title('条形图：hue=用餐时间', fontsize=12, fontweight='bold')\n",
        "\n",
        "# 4. 直方图：按用餐时间用颜色区分\n",
        "sns.histplot(data=tips, x='total_bill', hue='time', kde=True, ax=axes[1, 1])\n",
        "axes[1, 1].set_title('直方图：hue=用餐时间', fontsize=12, fontweight='bold')\n",
        "\n",
        "plt.suptitle('hue 参数：用颜色区分不同类别', fontsize=16, fontweight='bold', y=0.995)\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 3.4 size 参数 - 用点的大小表示数值\n",
        "\n",
        "`size` 参数用于根据数值变量的大小来控制数据点的大小，常用于散点图中。\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例：size 参数的使用\n",
        "tips = sns.load_dataset('tips')\n",
        "\n",
        "fig, axes = plt.subplots(1, 2, figsize=(14, 5))\n",
        "\n",
        "# 1. 使用 size 参数：点的大小表示用餐人数\n",
        "sns.scatterplot(data=tips, x='total_bill', y='tip', \n",
        "                size='size', sizes=(50, 300), ax=axes[0])\n",
        "axes[0].set_title('size 参数：点的大小表示用餐人数', fontsize=12, fontweight='bold')\n",
        "axes[0].set_xlabel('账单金额')\n",
        "axes[0].set_ylabel('小费金额')\n",
        "\n",
        "# 2. 结合 hue 和 size：同时用颜色和大小区分\n",
        "sns.scatterplot(data=tips, x='total_bill', y='tip', \n",
        "                hue='time', size='size', sizes=(50, 300), ax=axes[1])\n",
        "axes[1].set_title('hue + size：颜色表示时间，大小表示人数', fontsize=12, fontweight='bold')\n",
        "axes[1].set_xlabel('账单金额')\n",
        "axes[1].set_ylabel('小费金额')\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 3.5 style 参数 - 用不同标记样式区分类别\n",
        "\n",
        "`style` 参数用于根据分类变量用不同的标记样式（如圆形、方形、三角形等）来区分数据点。\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例：style 参数的使用\n",
        "tips = sns.load_dataset('tips')\n",
        "\n",
        "fig, axes = plt.subplots(1, 2, figsize=(14, 5))\n",
        "\n",
        "# 1. 使用 style 参数：不同的标记样式\n",
        "sns.scatterplot(data=tips, x='total_bill', y='tip', \n",
        "                style='smoker', markers=['o', 's'], ax=axes[0])\n",
        "axes[0].set_title('style 参数：标记样式区分是否吸烟', fontsize=12, fontweight='bold')\n",
        "axes[0].set_xlabel('账单金额')\n",
        "axes[0].set_ylabel('小费金额')\n",
        "\n",
        "# 2. 结合 hue 和 style：同时用颜色和标记样式区分\n",
        "sns.scatterplot(data=tips, x='total_bill', y='tip', \n",
        "                hue='time', style='smoker', \n",
        "                markers=['o', 's'], ax=axes[1])\n",
        "axes[1].set_title('hue + style：颜色表示时间，标记表示是否吸烟', fontsize=12, fontweight='bold')\n",
        "axes[1].set_xlabel('账单金额')\n",
        "axes[1].set_ylabel('小费金额')\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 3.6 col 和 row 参数 - 分面参数（创建子图）\n",
        "\n",
        "`col` 和 `row` 参数用于创建分面图（Facet Grid），根据分类变量自动创建多个子图。这些参数主要用于 `sns.relplot()`、`sns.catplot()` 等函数。\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例：col 和 row 参数的使用（分面图）\n",
        "tips = sns.load_dataset('tips')\n",
        "\n",
        "# 1. 使用 col 参数：按列创建子图\n",
        "g1 = sns.relplot(data=tips, x='total_bill', y='tip', \n",
        "                 col='time', kind='scatter', height=5, aspect=1)\n",
        "g1.fig.suptitle('col 参数：按用餐时间分列显示', fontsize=14, fontweight='bold', y=1.02)\n",
        "plt.tight_layout()\n",
        "plt.show()\n",
        "\n",
        "# 2. 使用 row 参数：按行创建子图\n",
        "g2 = sns.relplot(data=tips, x='total_bill', y='tip', \n",
        "                 row='smoker', kind='scatter', height=5, aspect=1)\n",
        "g2.fig.suptitle('row 参数：按是否吸烟分行显示', fontsize=14, fontweight='bold', y=1.02)\n",
        "plt.tight_layout()\n",
        "plt.show()\n",
        "\n",
        "# 3. 同时使用 col 和 row：创建网格子图\n",
        "g3 = sns.relplot(data=tips, x='total_bill', y='tip', \n",
        "                 col='time', row='smoker', kind='scatter', height=4, aspect=1)\n",
        "g3.fig.suptitle('col + row：创建网格子图', fontsize=14, fontweight='bold', y=1.02)\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 3.7 参数组合使用\n",
        "\n",
        "在实际应用中，我们经常需要组合使用多个参数来创建更丰富的信息可视化。\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 综合示例：组合使用多个参数\n",
        "tips = sns.load_dataset('tips')\n",
        "\n",
        "# 组合使用 data, x, y, hue, size, style\n",
        "fig, ax = plt.subplots(figsize=(12, 8))\n",
        "sns.scatterplot(\n",
        "    data=tips,              # 数据源\n",
        "    x='total_bill',         # x 轴变量\n",
        "    y='tip',                # y 轴变量\n",
        "    hue='time',             # 颜色区分：用餐时间\n",
        "    size='size',            # 大小表示：用餐人数\n",
        "    style='smoker',         # 标记样式：是否吸烟\n",
        "    sizes=(50, 300),        # 大小范围\n",
        "    markers=['o', 's'],     # 标记样式\n",
        "    alpha=0.7,              # 透明度\n",
        "    ax=ax\n",
        ")\n",
        "\n",
        "ax.set_title('综合示例：组合使用多个参数', fontsize=16, fontweight='bold')\n",
        "ax.set_xlabel('账单金额（美元）', fontsize=12)\n",
        "ax.set_ylabel('小费金额（美元）', fontsize=12)\n",
        "ax.legend(title='图例', bbox_to_anchor=(1.05, 1), loc='upper left')\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 4. 实际应用示例\n",
        "\n",
        "下面通过一个完整的实际应用示例，展示如何从数据准备到最终可视化的完整流程。\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 完整示例：从数据准备到可视化\n",
        "\n",
        "# 步骤1：准备数据（模拟销售数据）\n",
        "np.random.seed(42)\n",
        "dates = pd.date_range('2023-01-01', periods=365, freq='D')\n",
        "sales_data = pd.DataFrame({\n",
        "    '日期': dates,\n",
        "    '销售额': np.random.normal(1000, 200, 365) + np.sin(np.arange(365) * 2 * np.pi / 365) * 100,\n",
        "    '产品类别': np.random.choice(['电子产品', '服装', '食品'], 365, p=[0.4, 0.3, 0.3]),\n",
        "    '地区': np.random.choice(['北京', '上海', '广州', '深圳'], 365),\n",
        "    '促销': np.random.choice([True, False], 365, p=[0.3, 0.7])\n",
        "})\n",
        "\n",
        "# 添加月份列\n",
        "sales_data['月份'] = sales_data['日期'].dt.month\n",
        "sales_data['季度'] = sales_data['日期'].dt.quarter\n",
        "\n",
        "print(\"数据准备完成\")\n",
        "print(f\"数据形状: {sales_data.shape}\")\n",
        "print(f\"\\n前5行数据:\")\n",
        "print(sales_data.head())\n",
        "\n",
        "# 步骤2：数据转换（如果需要）\n",
        "# 例如：计算月度汇总\n",
        "monthly_summary = sales_data.groupby(['月份', '产品类别']).agg({\n",
        "    '销售额': 'mean'\n",
        "}).reset_index()\n",
        "\n",
        "print(f\"\\n月度汇总数据形状: {monthly_summary.shape}\")\n",
        "\n",
        "# 步骤3：创建可视化\n",
        "fig, axes = plt.subplots(2, 2, figsize=(16, 12))\n",
        "fig.suptitle('销售数据分析：完整流程示例', fontsize=18, fontweight='bold', y=0.995)\n",
        "\n",
        "# 子图1：时间序列（使用 data, x, y, hue）\n",
        "sns.lineplot(data=sales_data, x='日期', y='销售额', hue='产品类别', ax=axes[0, 0])\n",
        "axes[0, 0].set_title('时间序列：不同产品类别的销售额趋势', fontsize=12, fontweight='bold')\n",
        "axes[0, 0].tick_params(axis='x', rotation=45)\n",
        "\n",
        "# 子图2：箱线图（使用 data, x, y, hue）\n",
        "sns.boxplot(data=sales_data, x='产品类别', y='销售额', hue='促销', ax=axes[0, 1])\n",
        "axes[0, 1].set_title('箱线图：产品类别和促销对销售额的影响', fontsize=12, fontweight='bold')\n",
        "\n",
        "# 子图3：条形图（使用 data, x, y, hue）\n",
        "sns.barplot(data=monthly_summary, x='月份', y='销售额', hue='产品类别', ax=axes[1, 0])\n",
        "axes[1, 0].set_title('条形图：各月份不同产品类别的平均销售额', fontsize=12, fontweight='bold')\n",
        "\n",
        "# 子图4：分面图（使用 col 参数）\n",
        "g = sns.relplot(data=sales_data, x='日期', y='销售额', \n",
        "                col='地区', kind='line', height=4, aspect=1.2, col_wrap=2)\n",
        "g.fig.suptitle('分面图：不同地区的销售额趋势', fontsize=14, fontweight='bold', y=1.02)\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 5. 总结\n",
        "\n",
        "### 关键要点\n",
        "\n",
        "1. **数据格式**：\n",
        "   - Seaborn 主要使用 Pandas DataFrame\n",
        "   - 长格式数据更适合 Seaborn\n",
        "   - 使用 `pd.melt()` 将宽格式转换为长格式\n",
        "\n",
        "2. **基本绘图流程**：\n",
        "   - 准备数据 → 选择图表类型 → 调用函数 → 定制图表 → 显示/保存\n",
        "\n",
        "3. **核心参数**：\n",
        "   - `data`：数据源（DataFrame）\n",
        "   - `x`, `y`：坐标轴变量（列名）\n",
        "   - `hue`：用颜色区分类别\n",
        "   - `size`：用点的大小表示数值\n",
        "   - `style`：用不同标记样式区分类别\n",
        "   - `col`, `row`：分面参数，创建子图\n",
        "\n",
        "### 最佳实践\n",
        "\n",
        "- 始终使用 DataFrame 作为数据源\n",
        "- 确保数据为长格式\n",
        "- 使用列名作为变量名传入参数\n",
        "- 组合使用多个参数创建更丰富的信息可视化\n",
        "- 使用 Matplotlib 进行额外的图表定制\n"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "ml311",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.11.0"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 2
}
